﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RJ.Objects.PokerCards;
using RJ.Objects.GameEngine;

namespace RJ.Objects.GameRules
{
    public class EuchreRules
    {
        private CardSuit trumpSuit;
        public CardSuit TrumpSuit
        {
            get { return trumpSuit; }
            set
            {
                trumpSuit = value;
                Bowers[0] = new PlayingCard(trumpSuit, CardFace.Jack);
                Bowers[1] = LeftBower();
            }
        }

        public CardSuit PossibleTrump { get; set; }
        public PlayingCard TrickFirstCard { get; set; }
        public PlayingCard[] Bowers { get; set; }
        public GamePlayer CurrentTrickWinner { get; set; }
        public PlayingCard CurrentWinningCard { get; set; }
        public List<PlayingCard> CardsInPlay { get; set; }
        public int TrumpPasses { get; set; }
        public bool IsTrickComplete { get; set; }

        public EuchreRules()
        {
            Initialize();
        }

        public bool IsPlayIntentValid(PlayingCard card, Hand playerHand)
        {
            // make sure our card suit matching the trick first card is being played. If not verify that the hand
            // doesn't have any
            Console.WriteLine("Validating intent to play card: {0}", card.Name);
            if (card.Suit == TrickFirstCard.Suit) return true;
            if (!playerHand.Cards.Any(c => c.Suit == TrickFirstCard.Suit)) return true;
            return false;
        }

        public bool IsCalledTrumpValid(CardSuit suit)
        {
            Console.WriteLine("Validating called trump {0}", suit);
            return suit != PossibleTrump;
        }

        public void AcceptPlayedCard(PlayingCard card, GamePlayer player)
        {
            CardsInPlay.Add(card);

            if (CardsInPlay.Count == 1)
            {
                SetCurrentWinner(card, player);
                TrickFirstCard = card;
            }
            else
                CheckForCurrentWinner(card, player);

            IsTrickComplete = CardsInPlay.Count == 4;
        }

        private void CheckForCurrentWinner(PlayingCard card, GamePlayer player)
        {
            if (card.Equals(Bowers[0])
                || (card.Equals(Bowers[1]) && !CardsInPlay.Contains(Bowers[0]))
                || (card.Suit == TrickFirstCard.Suit && !CardsInPlay.Any(c => c.Suit == TrickFirstCard.Suit && (int)c.Face > (int)card.Face))
                || (card.Suit == trumpSuit && !CardsInPlay.Any(c => c.Suit == trumpSuit && (int)c.Face > (int)card.Face)))
            {
                SetCurrentWinner(card, player);
            }
        }

        private void SetCurrentWinner(PlayingCard card, GamePlayer player)
        {
            CurrentWinningCard = card;
            CurrentTrickWinner = player;
        }

        public void Initialize()
        {
            TrickFirstCard = null;
            CurrentTrickWinner = null;
            TrumpPasses = 0;
            Bowers = new PlayingCard[2];
            CardsInPlay = new List<PlayingCard>();
            IsTrickComplete = false;
        }

        private PlayingCard LeftBower()
        {
            if (trumpSuit == CardSuit.Clubs)
                return new PlayingCard(CardSuit.Spades, CardFace.Jack);
            else if (trumpSuit == CardSuit.Spades)
                return new PlayingCard(CardSuit.Clubs, CardFace.Jack);
            else if (trumpSuit == CardSuit.Hearts)
                return new PlayingCard(CardSuit.Diamonds, CardFace.Jack);
            else if (trumpSuit == CardSuit.Diamonds)
                return new PlayingCard(CardSuit.Hearts, CardFace.Jack);

            Console.WriteLine("The left bower could not be determined");
            throw new ApplicationException("The left bower couldn't be determined");
        }
    }
}
